-
Notifications
You must be signed in to change notification settings - Fork 333
refactor!: upgrade SDK to A2A 1.0 specs #572
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 1.0-a2a_proto_refactor
Are you sure you want to change the base?
refactor!: upgrade SDK to A2A 1.0 specs #572
Conversation
This updates the SDK to be A2A v1.0 compliant, all types are generated from the v1.0 a2a.proto. JSONRPC/HTTP+JSON transports are converted to use the a2a types encoded using ProtoJSON directly from the generated types.
BREAKING CHANGE: Replace Pydantic-based type system with protobuf types - Update all source files to use proto types directly from a2a_pb2 - Replace model_dump() with MessageToDict() for JSON serialization - Replace model_copy(deep=True) with CopyFrom() for proto cloning - Update Part usage from Part(root=TextPart(...)) to Part(text=...) - Update Role enum from Role.user to Role.ROLE_USER - Update TaskState enum to use TASK_STATE_* prefix - Add new types module with proto imports and SDK-specific extras - Add proto_utils module with identity conversion utilities - Fix REST handler resource name formats for push notification configs - Fix gRPC handler to use SubscribeToTask instead of TaskSubscription - Fix database task store to handle proto objects from ORM - Update all test files for proto patterns and assertions Tested: 601 tests passing, 23 skipped (expected - DB/crypto deps) Signed-off-by: Luca Muscariello <[email protected]>
Summary of ChangesHello @muscariello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request represents a foundational shift in the SDK's type system, moving from Pydantic models to native protobuf-generated types. This change aligns the SDK more closely with the A2A v1.0 specification, enhancing type consistency and performance. The migration necessitated extensive updates across the codebase, impacting how data is structured, serialized, and handled throughout the client and server components. While introducing several breaking changes to the API, the goal is to provide a more robust and future-proof foundation for A2A interactions. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This is a massive and well-executed refactoring to migrate the SDK from Pydantic types to protobuf-generated types, completing the upgrade to A2A v1.0. The changes are extensive, touching almost every part of the SDK, from client and server logic to transports, handlers, database models, and tests.
My review finds that the migration has been executed thoroughly and consistently. Key changes include:
- Replacing Pydantic models with protobuf messages from
a2a_pb2. - Updating data serialization from
model_dump()toMessageToDict()andParseDict(). - Refactoring client transports (
grpc,jsonrpc,rest) to work directly with protobuf types, which simplifies the code significantly. - Updating method signatures and data structures across the client and server components.
- Introducing a new
typesmodule as a central place for all type definitions. - Removing legacy client implementations.
The overall quality of the changes is high. The code is now more aligned with the A2A v1.0 specification, and the gRPC transport, in particular, is much cleaner. The test suite has been updated to reflect these changes, with a large number of tests passing.
I have a few suggestions for improving code maintainability and simplifying the logic in the AuthInterceptor and the database task store. Otherwise, the PR looks excellent.
| def _to_orm(self, task: Task) -> TaskModel: | ||
| """Maps a Pydantic Task to a SQLAlchemy TaskModel instance.""" | ||
| """Maps a Proto Task to a SQLAlchemy TaskModel instance.""" | ||
| # Convert proto to dict for storing in JSON columns | ||
| task_dict = MessageToDict(task, preserving_proto_field_name=True) | ||
| return self.task_model( | ||
| id=task.id, | ||
| context_id=task.context_id, | ||
| kind=task.kind, | ||
| status=task.status, | ||
| artifacts=task.artifacts, | ||
| history=task.history, | ||
| task_metadata=task.metadata, | ||
| kind='task', # Default kind for tasks | ||
| status=task_dict.get('status'), | ||
| artifacts=task_dict.get('artifacts', []), | ||
| history=task_dict.get('history', []), | ||
| task_metadata=task_dict.get('metadata'), | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function can be simplified. Instead of converting the entire Task protobuf message to a dictionary, you can pass the nested protobuf message objects (status, artifacts, history) directly to the TaskModel constructor. The PydanticType and PydanticListType decorators will handle their serialization. This avoids the overhead of MessageToDict for the whole task object.
def _to_orm(self, task: Task) -> TaskModel:
"""Maps a Proto Task to a SQLAlchemy TaskModel instance."""
return self.task_model(
id=task.id,
context_id=task.context_id,
kind='task', # Default kind for tasks
status=task.status,
artifacts=list(task.artifacts),
history=list(task.history),
task_metadata=MessageToDict(task.metadata) if task.metadata.fields else None,
)| def _from_orm(self, task_model: TaskModel) -> Task: | ||
| """Maps a SQLAlchemy TaskModel to a Pydantic Task instance.""" | ||
| # Map database columns to Pydantic model fields | ||
| """Maps a SQLAlchemy TaskModel to a Proto Task instance.""" | ||
| # The ORM columns return proto objects for status, artifacts, history | ||
| # We need to convert them back to dicts for ParseDict | ||
| task_data_from_db = { | ||
| 'id': task_model.id, | ||
| 'context_id': task_model.context_id, | ||
| 'kind': task_model.kind, | ||
| 'status': task_model.status, | ||
| 'artifacts': task_model.artifacts, | ||
| 'history': task_model.history, | ||
| 'metadata': task_model.task_metadata, # Map task_metadata column to metadata field | ||
| } | ||
| # Pydantic's model_validate will parse the nested dicts/lists from JSON | ||
| return Task.model_validate(task_data_from_db) | ||
| # Add status if present (already a proto object from PydanticType) | ||
| if task_model.status is not None: | ||
| task_data_from_db['status'] = MessageToDict(task_model.status, preserving_proto_field_name=True) | ||
| # Add artifacts if present (list of proto objects) | ||
| if task_model.artifacts: | ||
| task_data_from_db['artifacts'] = [ | ||
| MessageToDict(a, preserving_proto_field_name=True) if hasattr(a, 'DESCRIPTOR') else a | ||
| for a in task_model.artifacts | ||
| ] | ||
| # Add history if present (list of proto objects) | ||
| if task_model.history: | ||
| task_data_from_db['history'] = [ | ||
| MessageToDict(m, preserving_proto_field_name=True) if hasattr(m, 'DESCRIPTOR') else m | ||
| for m in task_model.history | ||
| ] | ||
| # Add metadata if present | ||
| if task_model.task_metadata is not None: | ||
| task_data_from_db['metadata'] = task_model.task_metadata | ||
| # Use ParseDict to create proto from dict | ||
| return ParseDict(task_data_from_db, Task()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function seems overly complex. Since PydanticType and PydanticListType already deserialize the JSON from the database into protobuf message objects, you can construct the final Task protobuf object directly using these objects, rather than converting them back to dictionaries and then parsing the whole dictionary again. This would be more efficient and easier to read.
def _from_orm(self, task_model: TaskModel) -> Task:
"""Maps a SQLAlchemy TaskModel to a Proto Task instance."""
task = Task(
id=task_model.id,
context_id=task_model.context_id,
)
if task_model.status:
task.status.CopyFrom(task_model.status)
if task_model.artifacts:
task.artifacts.extend(task_model.artifacts)
if task_model.history:
task.history.extend(task_model.history)
if task_model.task_metadata:
task.metadata.update(task_model.task_metadata)
return task
src/a2a/client/auth/interceptor.py
Outdated
| which = scheme.WhichOneof('scheme') | ||
| if which == 'api_key_security_scheme': | ||
| return scheme.api_key_security_scheme | ||
| elif which == 'http_auth_security_scheme': | ||
| return scheme.http_auth_security_scheme | ||
| elif which == 'oauth2_security_scheme': | ||
| return scheme.oauth2_security_scheme | ||
| elif which == 'open_id_connect_security_scheme': | ||
| return scheme.open_id_connect_security_scheme | ||
| elif which == 'mtls_security_scheme': | ||
| return scheme.mtls_security_scheme | ||
| return None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
- Fix agent_app.py Part access pattern for proto (HasField/direct access) - Fix ClientEvent handling in E2E tests (StreamResponse, not Task) - Fix notifications_app.py to serialize proto Task to dict - Update SetTaskPushNotificationConfigRequest interface in handlers - Update default_request_handler to use request.parent instead of name - Update jsonrpc_handler to pass full request to handler - Update unit tests to use SetTaskPushNotificationConfigRequest Signed-off-by: Luca Muscariello <[email protected]>
buf.gen.yaml
Outdated
| inputs: | ||
| - git_repo: https://github.com/a2aproject/A2A.git | ||
| ref: main | ||
| ref: transports |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to change this back to "main" to pick up the latest fixes from the a2a.proto and before we merge we need to switch to the tag for v1.0 (when its cut)
| scheme_def = scheme_def_union.root | ||
| scheme_def = _get_security_scheme_value(scheme_def_union) | ||
| if not scheme_def: | ||
| continue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personal preference would be to use the functions available from proto to do the matching below instead of ending up with a non-statically typed function here. E.g.
match scheme.WhichOneof('scheme'):
case 'http_auth_security_scheme' if scheme.http_auth_security_scheme.lower() == 'bearer':
...tbh I think it would read better as a set of if blocks:
scheme = agent_card.security_schemes.get(scheme_name)
if scheme.HasField('http_auth_security_scheme') and scheme.http_auth_security_scheme.lower() == 'bearer':
...
if scheme.HasField('oauth2_security_scheme') or scheme.HasField('open_id_connect_security_scheme'):
...There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure how's HasField improves things here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As explained our call, its mostly about readability, but also prevent us using reflection to check the python types, and instead we can just rely on the boolean check of "does the request have this field set" then it can use it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check now @Tehsmash
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't seem to be able to resolve my own threads on the a2a repos, but I'll leave a LGTM if I think it should be resolved.
src/a2a/types/extras.py
Outdated
|
|
||
| # Alias for backward compatibility - the proto uses SendMessageRequest | ||
| # where old code might use MessageSendParams | ||
| from a2a.types.a2a_pb2 import SendMessageRequest as MessageSendParams |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets not do this, any code that is already using a2a.types.MessageSendParams would need change the imports anyway and I think this will be confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a quick removal that in any case is supposed to be removed before the PR is complete.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
src/a2a/types/extras.py
Outdated
| ) | ||
|
|
||
| # Alias for streaming - same as SendMessageRequest in the proto | ||
| SendStreamingMessageRequest = SendMessageRequest = MessageSendParams |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-1, lets just update the code to use SendMessageRequest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
src/a2a/types/extras.py
Outdated
| """Transport protocol string constants for backward compatibility.""" | ||
| jsonrpc = "JSONRPC" | ||
| http_json = "HTTP+JSON" | ||
| grpc = "GRPC" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the client code I add these as constants, if we want to put them somewhere common I would add a "constants.py" / constants module outside of "types".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To move this elsewhere I would have to solve a circular dependency first. There needs to be additional refactoring work before I can do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am moving things from the refactor out of extras.py until it is empty. Then I will remove the file. A few more commits I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
src/a2a/types/extras.py
Outdated
| # Union of all A2A error types | ||
| A2AError = Union[ | ||
| JSONRPCError, | ||
| JSONParseError, | ||
| InvalidRequestError, | ||
| MethodNotFoundError, | ||
| InvalidParamsError, | ||
| InternalError, | ||
| TaskNotFoundError, | ||
| TaskNotCancelableError, | ||
| PushNotificationNotSupportedError, | ||
| UnsupportedOperationError, | ||
| ContentTypeNotSupportedError, | ||
| InvalidAgentResponseError, | ||
| AuthenticatedExtendedCardNotConfiguredError, | ||
| ] | ||
|
|
||
|
|
||
| class JSONRPCRequest(A2ABaseModel): | ||
| """Represents a JSON-RPC 2.0 Request object.""" | ||
|
|
||
| jsonrpc: Literal["2.0"] = "2.0" | ||
| method: str | ||
| params: Any | None = None | ||
| id: str | int | None = None | ||
|
|
||
|
|
||
| class JSONRPCResponse(A2ABaseModel): | ||
| """Represents a JSON-RPC 2.0 Success Response object.""" | ||
|
|
||
| jsonrpc: Literal["2.0"] = "2.0" | ||
| result: Any | ||
| id: str | int | None = None | ||
|
|
||
|
|
||
| class JSONRPCErrorResponse(A2ABaseModel): | ||
| """Represents a JSON-RPC 2.0 Error Response object.""" | ||
|
|
||
| jsonrpc: Literal["2.0"] = "2.0" | ||
| error: A2AError | ||
| id: str | int | None = None | ||
|
|
||
|
|
||
| # Type alias for A2A requests (union of all request types) | ||
| # This maps to the various request message types in the proto | ||
| from a2a.types.a2a_pb2 import ( | ||
| CancelTaskRequest, | ||
| GetExtendedAgentCardRequest, | ||
| GetTaskPushNotificationConfigRequest, | ||
| GetTaskRequest, | ||
| SendMessageRequest, | ||
| SetTaskPushNotificationConfigRequest, | ||
| SubscribeToTaskRequest, | ||
| ) | ||
|
|
||
| A2ARequest = Union[ | ||
| SendMessageRequest, | ||
| GetTaskRequest, | ||
| CancelTaskRequest, | ||
| SetTaskPushNotificationConfigRequest, | ||
| GetTaskPushNotificationConfigRequest, | ||
| SubscribeToTaskRequest, | ||
| GetExtendedAgentCardRequest, | ||
| ] | ||
|
|
||
|
|
||
| # JSON-RPC Success Response types | ||
| # These wrap the result of successful RPC calls | ||
| # Note: result is typed as Any to allow both proto messages and dicts | ||
| class GetTaskSuccessResponse(A2ABaseModel): | ||
| """Success response for GetTask RPC.""" | ||
| jsonrpc: Literal["2.0"] = "2.0" | ||
| id: str | int | None = None | ||
| result: Any | ||
|
|
||
|
|
||
| class CancelTaskSuccessResponse(A2ABaseModel): | ||
| """Success response for CancelTask RPC.""" | ||
| jsonrpc: Literal["2.0"] = "2.0" | ||
| id: str | int | None = None | ||
| result: Any | ||
|
|
||
|
|
||
| class SendMessageSuccessResponse(A2ABaseModel): | ||
| """Success response for SendMessage RPC.""" | ||
| jsonrpc: Literal["2.0"] = "2.0" | ||
| id: str | int | None = None | ||
| result: Any | ||
|
|
||
|
|
||
| class SendStreamingMessageSuccessResponse(A2ABaseModel): | ||
| """Success response for streaming message RPC.""" | ||
| jsonrpc: Literal["2.0"] = "2.0" | ||
| id: str | int | None = None | ||
| result: Any # Streaming events | ||
|
|
||
|
|
||
| class SetTaskPushNotificationConfigSuccessResponse(A2ABaseModel): | ||
| """Success response for SetTaskPushNotificationConfig RPC.""" | ||
| jsonrpc: Literal["2.0"] = "2.0" | ||
| id: str | int | None = None | ||
| result: Any | ||
|
|
||
|
|
||
| class GetTaskPushNotificationConfigSuccessResponse(A2ABaseModel): | ||
| """Success response for GetTaskPushNotificationConfig RPC.""" | ||
| jsonrpc: Literal["2.0"] = "2.0" | ||
| id: str | int | None = None | ||
| result: Any | ||
|
|
||
|
|
||
| class ListTaskPushNotificationConfigSuccessResponse(A2ABaseModel): | ||
| """Success response for ListTaskPushNotificationConfig RPC.""" | ||
| jsonrpc: Literal["2.0"] = "2.0" | ||
| id: str | int | None = None | ||
| result: Any | ||
|
|
||
|
|
||
| class DeleteTaskPushNotificationConfigSuccessResponse(A2ABaseModel): | ||
| """Success response for DeleteTaskPushNotificationConfig RPC.""" | ||
| jsonrpc: Literal["2.0"] = "2.0" | ||
| id: str | int | None = None | ||
| result: None = None | ||
|
|
||
|
|
||
| class GetAuthenticatedExtendedCardSuccessResponse(A2ABaseModel): | ||
| """Success response for GetAuthenticatedExtendedCard RPC.""" | ||
| jsonrpc: Literal["2.0"] = "2.0" | ||
| id: str | int | None = None | ||
| result: Any # AgentCard |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let not add our own implementation of this. In the client code I pull in the "jsonrpc" package from pypi, which has the JSONRPC20Response type already defined, then we only need to concern ourselves with populating the result or error fields.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
| # A2ARequest is now a Union type of proto messages, so we can't use | ||
| # model_json_schema. Instead, we just mark it as added without | ||
| # adding the schema since proto types don't have Pydantic schemas. | ||
| # The OpenAPI schema will still be functional for the endpoints. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LOL ... "the code doesn't support this any more so we'll just mark this test as passed anyway"
In all seriousness this should be replaced by the generated a2a.json schema I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not using a2a.json at all. So need to rethink about this test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I meant is that if fastapi wants to serve an OpenAPI schema, then we need to use the a2a.json instead of generating one from the python types.
| 'tasks/pushNotificationConfig/delete': DeleteTaskPushNotificationConfigRequest, | ||
| 'tasks/resubscribe': TaskResubscriptionRequest, | ||
| 'agent/authenticatedExtendedCard': GetExtendedAgentCardRequest, | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method names have changed to align with the gRPC ones, i.e message/send is now "SendMessage". We need to fix that in the client and here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I have fixed this everywhere now. I will keep checking...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
| JSONRPCError, | ||
| JSONRPCErrorResponse, | ||
| JSONRPCRequest, | ||
| JSONRPCResponse, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets pull in the jsonrpc dependency so that we can remove these from the types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
| id=request_id, error=error | ||
| ) | ||
|
|
||
| return self._create_response(context, handler_result) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should revisit this code and match on the JSON RPC method first then perform the correct decoding as there are body types like "SendMessageRequest" which are reused for different methods.
For example:
def _process_request(self, request: JSONRPC20Request):
match request.method:
case "SendMessage":
input: SendMessageRequest = ParseDict(request.params, SendMessageRequest())
result = await self.handler.on_send_message(input)
case "CancelTask":
input: CancelTaskRequest = ParseDict(request.params, CancelTaskRequest())
...
...There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still think this would be cleaner than doing METHOD_TO_MODEL first and matching on the classes after the fact. And makes it more obvious IMO that the final / default case of the "match" would be "MethodNotFound".
| """ | ||
| # Create task manager and validate existing task | ||
| # Proto empty strings should be treated as None | ||
| task_id = params.request.task_id or None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to confirm if "task_id" should be just the UUID, or should be in the form "tasks/".
I think AIP for this said that it should be "tasks/" because this is the FQN for the task.
| TaskNotCancelableError, | ||
| TaskNotFoundError, | ||
| UnsupportedOperationError, | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should move all these errors to errors.py instead of extras.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
src/a2a/utils/parts.py
Outdated
| A list of dictionaries containing the data from any `DataPart` objects found. | ||
| """ | ||
| return [part.root.data for part in parts if isinstance(part.root, DataPart)] | ||
| from google.protobuf.json_format import MessageToDict |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for an inline import, lets move this to the top of the file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can remove this file and its classes/functions, as we're using the proto types everywhere now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of the stuff from here is gone, i think we can nuke the helper function here if we fix the response from the default_request_handler.
| for part in request.parts: | ||
| if isinstance(part.root, TextPart) and not part.root.text: | ||
| raise ValueError('TextPart content cannot be empty') | ||
| if part.text is not None and not part.text: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if part.text is not None and not part.text: | |
| if part.HasField('text') and not part.text: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
| del task_copy.history[:] | ||
| task_copy.history.extend(limited_history) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| del task_copy.history[:] | |
| task_copy.history.extend(limited_history) | |
| task_copy.history[:] = limited_history |
- Fix E402: Move telemetry import to top in default_request_handler.py - Fix TRY300/RET504: Return directly in grpc_handler.py try blocks - Fix TRY004: Add noqa for valid ValueError in database_push_notification_config_store.py - Fix pyright: Add else branch for unbound client_event in base_client.py - Fix pyright: Add cast for rpc_request.data in jsonrpc.py transport All linter checks now pass: - ruff check: 0 errors - ruff format: 78 files formatted - mypy: 0 errors in 78 files - pyright: 0 errors, 0 warnings All 730 tests pass (including PostgreSQL and MySQL database tests)
src/a2a/client/auth/interceptor.py
Outdated
|
|
||
|
|
||
| def _get_security_scheme_value(scheme: SecurityScheme): | ||
| def _get_security_scheme_value(scheme: SecurityScheme) -> _SecuritySchemeValue: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this change has just proven my point about moving this inline in the function below and changing how the "match" is done.
| task.history.append(task.status.message) | ||
| if event.metadata: | ||
| task.metadata.update(event.metadata) | ||
| task.metadata.update(dict(event.metadata)) # type: ignore[arg-type] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should use task.metadata.MergeFrom/CopyFrom here depending on the desired behaviour
…ry directly - Update JSONRPCHandler to return dict[str, Any] instead of Pydantic RootModels - Update response_helpers to build dicts with JSON-RPC 2.0 structure - Remove unused Pydantic response types from types module - Fix proto dependency loading in a2a_pb2.py - Update all tests to check dict responses instead of Pydantic models - Add TransportProtocol constants to utils module
…iases - Rename on_resubscribe_to_task to on_subscribe_to_task across all handlers - Update METHOD_TO_MODEL with gRPC-style method names (SendMessage, GetTask, etc.) - Update JSON-RPC client to use new method names - Fix ListTaskPushNotificationConfigResponse to use 'configs' field - Remove TaskResubscriptionRequest alias from extras.py - Update TransportProtocol imports to use a2a.utils.constants - Fix on_get_task_push_notification_config params type - Update all tests for new method names and response types
…s.py - Moved all error type definitions (JSONRPCError, A2AError, etc.) to utils/errors.py - Updated all imports across 15 files to use a2a.utils.errors - Defined A2ARequest union inline in types/__init__.py - Deleted the now-redundant extras.py file - Re-exported error types from types/__init__.py for public API
| or agent_card.security is None | ||
| or agent_card.security_schemes is None | ||
| or not agent_card.security | ||
| or not agent_card.security_schemes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Double checking the protobuf docs https://protobuf.dev/reference/python/python-generated/#embedded_message it sounds like we may need to use agent_card.HasField("...") this separates the difference between agent_card.security set, not set and set but empty from what I can tell.
| scheme_def = scheme_def_union.root | ||
| scheme_def = _get_security_scheme_value(scheme_def_union) | ||
| if not scheme_def: | ||
| continue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't seem to be able to resolve my own threads on the a2a repos, but I'll leave a LGTM if I think it should be resolved.
| class A2ABaseModel(BaseModel): | ||
| """Base model for all A2A SDK types.""" | ||
|
|
||
| model_config = { | ||
| 'extra': 'allow', | ||
| 'populate_by_name': True, | ||
| 'arbitrary_types_allowed': True, | ||
| } | ||
|
|
||
|
|
||
| # JSON-RPC Error types - A2A specific error codes | ||
| class JSONRPCError(A2ABaseModel): | ||
| """Represents a JSON-RPC 2.0 Error object.""" | ||
|
|
||
| code: int | ||
| """A number that indicates the error type that occurred.""" | ||
| message: str | ||
| """A string providing a short description of the error.""" | ||
| data: Any | None = None | ||
| """Additional information about the error.""" | ||
|
|
||
|
|
||
| class JSONParseError(A2ABaseModel): | ||
| """JSON-RPC parse error (-32700).""" | ||
|
|
||
| code: Literal[-32700] = -32700 | ||
| message: str = 'Parse error' | ||
| data: Any | None = None | ||
|
|
||
|
|
||
| class InvalidRequestError(A2ABaseModel): | ||
| """JSON-RPC invalid request error (-32600).""" | ||
|
|
||
| code: Literal[-32600] = -32600 | ||
| message: str = 'Invalid Request' | ||
| data: Any | None = None | ||
|
|
||
|
|
||
| class MethodNotFoundError(A2ABaseModel): | ||
| """JSON-RPC method not found error (-32601).""" | ||
|
|
||
| code: Literal[-32601] = -32601 | ||
| message: str = 'Method not found' | ||
| data: Any | None = None | ||
|
|
||
|
|
||
| class InvalidParamsError(A2ABaseModel): | ||
| """JSON-RPC invalid params error (-32602).""" | ||
|
|
||
| code: Literal[-32602] = -32602 | ||
| message: str = 'Invalid params' | ||
| data: Any | None = None | ||
|
|
||
|
|
||
| class InternalError(A2ABaseModel): | ||
| """JSON-RPC internal error (-32603).""" | ||
|
|
||
| code: Literal[-32603] = -32603 | ||
| message: str = 'Internal error' | ||
| data: Any | None = None | ||
|
|
||
|
|
||
| class TaskNotFoundError(A2ABaseModel): | ||
| """A2A-specific error for task not found (-32001).""" | ||
|
|
||
| code: Literal[-32001] = -32001 | ||
| message: str = 'Task not found' | ||
| data: Any | None = None | ||
|
|
||
|
|
||
| class TaskNotCancelableError(A2ABaseModel): | ||
| """A2A-specific error for task not cancelable (-32002).""" | ||
|
|
||
| code: Literal[-32002] = -32002 | ||
| message: str = 'Task cannot be canceled' | ||
| data: Any | None = None | ||
|
|
||
|
|
||
| class PushNotificationNotSupportedError(A2ABaseModel): | ||
| """A2A-specific error for push notification not supported (-32003).""" | ||
|
|
||
| code: Literal[-32003] = -32003 | ||
| message: str = 'Push Notification is not supported' | ||
| data: Any | None = None | ||
|
|
||
|
|
||
| class UnsupportedOperationError(A2ABaseModel): | ||
| """A2A-specific error for unsupported operation (-32004).""" | ||
|
|
||
| code: Literal[-32004] = -32004 | ||
| message: str = 'This operation is not supported' | ||
| data: Any | None = None | ||
|
|
||
|
|
||
| class ContentTypeNotSupportedError(A2ABaseModel): | ||
| """A2A-specific error for content type not supported (-32005).""" | ||
|
|
||
| code: Literal[-32005] = -32005 | ||
| message: str = 'Incompatible content types' | ||
| data: Any | None = None | ||
|
|
||
|
|
||
| class InvalidAgentResponseError(A2ABaseModel): | ||
| """A2A-specific error for invalid agent response (-32006).""" | ||
|
|
||
| code: Literal[-32006] = -32006 | ||
| message: str = 'Invalid agent response' | ||
| data: Any | None = None | ||
|
|
||
|
|
||
| class AuthenticatedExtendedCardNotConfiguredError(A2ABaseModel): | ||
| """A2A-specific error for authenticated extended card not configured (-32007).""" | ||
|
|
||
| code: Literal[-32007] = -32007 | ||
| message: str = 'Authenticated Extended Card is not configured' | ||
| data: Any | None = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The A2A exception's here shouldn't have JSONRPC specific data, the JSONRPC server/client components should have a map from the exceptions to the JSONRPC code and vice-versa for raising an exception on receipt of a JSONRPCError
JSONRPC specific exceptions like MethodNotFound should live in the JSONRPC implementation code or a separate JSONRPC common package IMO.
| TaskNotCancelableError, | ||
| TaskNotFoundError, | ||
| UnsupportedOperationError, | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
| 'tasks/pushNotificationConfig/delete': DeleteTaskPushNotificationConfigRequest, | ||
| 'tasks/resubscribe': TaskResubscriptionRequest, | ||
| 'agent/authenticatedExtendedCard': GetExtendedAgentCardRequest, | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
| async def on_resubscribe_to_task( | ||
| self, | ||
| params: TaskIdParams, | ||
| params: CancelTaskRequest, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
src/a2a/server/models.py
Outdated
| if isinstance(self.pydantic_type, type) and issubclass(self.pydantic_type, ProtoMessage): | ||
| return ParseDict(value, self.pydantic_type()) # type: ignore[return-value] | ||
| # Assume it's a Pydantic model | ||
| return self.pydantic_type.model_validate(value) # type: ignore[union-attr] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is still relevant to models.py even though its been disconnected. You can resolve this and I'll open a new comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to support Pydantic here IMO, just need to support the protobuf types.
One thought: We need to understand if we need to support old messages/tasks stored in the DB and translate them to the protobuf types. Otherwise we may require people to drop the DBs for their Agents
src/a2a/utils/parts.py
Outdated
| A list of dictionaries containing the data from any `DataPart` objects found. | ||
| """ | ||
| return [part.root.data for part in parts if isinstance(part.root, DataPart)] | ||
| from google.protobuf.json_format import MessageToDict |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of the stuff from here is gone, i think we can nuke the helper function here if we fix the response from the default_request_handler.
# Description Refine error management for the streaming operation. Previously, errors were converted into stream parts, resulting in the loss of status info. The updated logic now first verifies if the request was successful; if it failed, a client error is returned, preserving the relevant status information. - [x] Follow the [`CONTRIBUTING` Guide](https://github.com/a2aproject/a2a-python/blob/main/CONTRIBUTING.md). - [x] Make your Pull Request title in the <https://www.conventionalcommits.org/> specification. - Important Prefixes for [release-please](https://github.com/googleapis/release-please): - `fix:` which represents bug fixes, and correlates to a [SemVer](https://semver.org/) patch. - `feat:` represents a new feature, and correlates to a SemVer minor. - `feat!:`, or `fix!:`, `refactor!:`, etc., which represent a breaking change (indicated by the `!`) and will result in a SemVer major. - [x] Ensure the tests and linter pass (Run `bash scripts/format.sh` from the repository root to format) - [x] Appropriate docs were updated (if necessary) Fixes a2aproject#502 🦕
🤖 I have created a release *beep* *boop* --- ## [0.3.20](a2aproject/a2a-python@v0.3.19...v0.3.20) (2025-12-03) ### Bug Fixes * Improve streaming errors handling ([a2aproject#576](a2aproject#576)) ([7ea7475](a2aproject@7ea7475)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
|
@Tehsmash I am going to wait a few more days for the A2A 1.0 specs to get the most recent updates. |
# Description Just fixing various typos discovered while reading code of the repo: see commit diffs for details Cheers Didier - [X] Follow the [`CONTRIBUTING` Guide](https://github.com/a2aproject/a2a-python/blob/main/CONTRIBUTING.md). - [X] Make your Pull Request title in the <https://www.conventionalcommits.org/> specification. - [X] Ensure the tests and linter pass (Run `bash scripts/format.sh` from the repository root to format) - [X] Appropriate docs were updated (if necessary) Fixes #<issue_number_goes_here> 🦕 N/A --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…ect#581) This PR introduces digital signatures for Agent Cards to ensure authenticity and integrity, adhering to the A2A specification for [Agent Card Signing (Section 8.4).](https://a2a-protocol.org/latest/specification/#84-agent-card-signing) ## Changes: - Implement `Canonicalization` Logic (`src/a2a/utils/signing.py`) - Add `Signing` and `Verification` Utilities (`src/a2a/utils/signing.py`): - `create_agent_card_signer` which generates an `agent_card_signer` for signing `AgentCards` - `create_signature_verifier` which generates a `signature_verifier` for verification of `AgentCard` signatures - Enable signature verification support for `json-rpc`, `rest` and `gRPC` transports - Add Protobuf Conversion for Signatures (`src/a2a/utils/proto_utils.py`) ensuring `AgentCardSignature` can be serialized and deserialized for gRPC transport - Add related tests: - integration tests for fetching signed cards from the Server - unit tests for signing util - unit tests for protobuf conversions - [x] Follow the [`CONTRIBUTING` Guide](https://github.com/a2aproject/a2a-python/blob/main/CONTRIBUTING.md). - [x] Make your Pull Request title in the <https://www.conventionalcommits.org/> specification. - Important Prefixes for [release-please](https://github.com/googleapis/release-please): - `fix:` which represents bug fixes, and correlates to a [SemVer](https://semver.org/) patch. - `feat:` represents a new feature, and correlates to a SemVer minor. - `feat!:`, or `fix!:`, `refactor!:`, etc., which represent a breaking change (indicated by the `!`) and will result in a SemVer major. - [x] Ensure the tests and linter pass (Run `bash scripts/format.sh` from the repository root to format) - [x] Appropriate docs were updated (if necessary) Release-As: 0.3.21
# Description Read further and discovered this additional (and final) set of typos
🤖 I have created a release *beep* *boop* --- ## [0.3.21](a2aproject/a2a-python@v0.3.20...v0.3.21) (2025-12-12) ### Documentation * Fixing typos ([a2aproject#586](a2aproject#586)) ([5fea21f](a2aproject@5fea21f)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
…ject#594) # Description This change allows passing custom `task_id_generator` and `context_id_generator` functions to the `SimpleRequestContextBuilder`. This provides flexibility in how task and context IDs are generated, defaulting to the previous behavior if no generators are provided. Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: - [x] Follow the [`CONTRIBUTING` Guide](https://github.com/a2aproject/a2a-python/blob/main/CONTRIBUTING.md). - [x] Make your Pull Request title in the <https://www.conventionalcommits.org/> specification. - Important Prefixes for [release-please](https://github.com/googleapis/release-please): - `fix:` which represents bug fixes, and correlates to a [SemVer](https://semver.org/) patch. - `feat:` represents a new feature, and correlates to a SemVer minor. - `feat!:`, or `fix!:`, `refactor!:`, etc., which represent a breaking change (indicated by the `!`) and will result in a SemVer major. - [x] Ensure the tests and linter pass (Run `bash scripts/format.sh` from the repository root to format) - [x] Appropriate docs were updated (if necessary) Fixes #<issue_number_goes_here> 🦕
# Description Adding 2 more tests to user.py to improve build code coverage - [X] Follow the [`CONTRIBUTING` Guide](https://github.com/a2aproject/a2a-python/blob/main/CONTRIBUTING.md). - [X] Make your Pull Request title in the <https://www.conventionalcommits.org/> specification. - [X] Ensure the tests and linter pass (Run `bash scripts/format.sh` from the repository root to format) - [N/A] Appropriate docs were updated (if necessary) Fixes #<issue_number_goes_here> 🦕 N/A --------- Co-authored-by: Lukasz Kawka <[email protected]>
# Description Adding 21 tests for client/card_resolver.py They all pass: ``` ========================= test session starts ============================== collecting ... collected 21 items tests/client/test_card_resolver.py::TestA2ACardResolverInit::test_init_with_defaults PASSED [ 4%] tests/client/test_card_resolver.py::TestA2ACardResolverInit::test_init_with_custom_path PASSED [ 9%] tests/client/test_card_resolver.py::TestA2ACardResolverInit::test_init_strips_leading_slash_from_agent_card_path PASSED [ 14%] tests/client/test_card_resolver.py::TestGetAgentCard::test_get_agent_card_success_default_path PASSED [ 19%] tests/client/test_card_resolver.py::TestGetAgentCard::test_get_agent_card_success_custom_path PASSED [ 23%] tests/client/test_card_resolver.py::TestGetAgentCard::test_get_agent_card_strips_leading_slash_from_relative_path PASSED [ 28%] tests/client/test_card_resolver.py::TestGetAgentCard::test_get_agent_card_with_http_kwargs PASSED [ 33%] tests/client/test_card_resolver.py::TestGetAgentCard::test_get_agent_card_root_path PASSED [ 38%] tests/client/test_card_resolver.py::TestGetAgentCard::test_get_agent_card_http_status_error PASSED [ 42%] tests/client/test_card_resolver.py::TestGetAgentCard::test_get_agent_card_json_decode_error PASSED [ 47%] tests/client/test_card_resolver.py::TestGetAgentCard::test_get_agent_card_request_error PASSED [ 52%] tests/client/test_card_resolver.py::TestGetAgentCard::test_get_agent_card_validation_error PASSED [ 57%] tests/client/test_card_resolver.py::TestGetAgentCard::test_get_agent_card_logs_success PASSED [ 61%] tests/client/test_card_resolver.py::TestGetAgentCard::test_get_agent_card_none_relative_path PASSED [ 66%] tests/client/test_card_resolver.py::TestGetAgentCard::test_get_agent_card_empty_string_relative_path PASSED [ 71%] tests/client/test_card_resolver.py::TestGetAgentCard::test_get_agent_card_different_status_codes[400] PASSED [ 76%] tests/client/test_card_resolver.py::TestGetAgentCard::test_get_agent_card_different_status_codes[401] PASSED [ 80%] tests/client/test_card_resolver.py::TestGetAgentCard::test_get_agent_card_different_status_codes[403] PASSED [ 85%] tests/client/test_card_resolver.py::TestGetAgentCard::test_get_agent_card_different_status_codes[500] PASSED [ 90%] tests/client/test_card_resolver.py::TestGetAgentCard::test_get_agent_card_different_status_codes[502] PASSED [ 95%] tests/client/test_card_resolver.py::TestGetAgentCard::test_get_agent_card_returns_agent_card_instance PASSED [100%] ======================== 21 passed, 2 warnings in 0.11s ======================== ``` - [X] Follow the [`CONTRIBUTING` Guide](https://github.com/a2aproject/a2a-python/blob/main/CONTRIBUTING.md). - [X] Make your Pull Request title in the <https://www.conventionalcommits.org/> specification. - [X] Ensure the tests and linter pass (Run `bash scripts/format.sh` from the repository root to format) - [N/A ] Appropriate docs were updated (if necessary) Fixes #<issue_number_goes_here> 🦕 N/A --------- Co-authored-by: Lukasz Kawka <[email protected]>
…r` (a2aproject#593) # Description Previously, the `JSON-RPC` and `REST` protocols verified agent card signatures after calling `A2ACardResolver.get_agent_card`. This change moves the signature verification logic inside the `A2ACardResolver.get_agent_card` method and adds a unit test to test_card_resolver.py Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: - [x] Follow the [`CONTRIBUTING` Guide](https://github.com/a2aproject/a2a-python/blob/main/CONTRIBUTING.md). - [x] Make your Pull Request title in the <https://www.conventionalcommits.org/> specification. - Important Prefixes for [release-please](https://github.com/googleapis/release-please): - `fix:` which represents bug fixes, and correlates to a [SemVer](https://semver.org/) patch. - `feat:` represents a new feature, and correlates to a SemVer minor. - `feat!:`, or `fix!:`, `refactor!:`, etc., which represent a breaking change (indicated by the `!`) and will result in a SemVer major. - [x] Ensure the tests and linter pass (Run `bash scripts/format.sh` from the repository root to format) - [x] Appropriate docs were updated (if necessary)
🤖 I have created a release *beep* *boop* --- ## [0.3.22](a2aproject/a2a-python@v0.3.21...v0.3.22) (2025-12-16) ### Features * Add custom ID generators to `SimpleRequestContextBuilder` ([a2aproject#594](a2aproject#594)) ([04bcafc](a2aproject@04bcafc)) ### Code Refactoring * Move agent card signature verification into `A2ACardResolver` ([6fa6a6c](a2aproject@6fa6a6c)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
# Description Adding 13 tests for server/tasks/id_generator.py They all pass: ``` ============================= test session starts ============================== collecting ... collected 13 items tests/server/tasks/test_id_generator.py::TestIDGeneratorContext::test_context_creation_with_all_fields PASSED [ 7%] tests/server/tasks/test_id_generator.py::TestIDGeneratorContext::test_context_creation_with_defaults PASSED [ 15%] tests/server/tasks/test_id_generator.py::TestIDGeneratorContext::test_context_creation_with_partial_fields[kwargs0-task_123-None] PASSED [ 23%] tests/server/tasks/test_id_generator.py::TestIDGeneratorContext::test_context_creation_with_partial_fields[kwargs1-None-context_456] PASSED [ 30%] tests/server/tasks/test_id_generator.py::TestIDGeneratorContext::test_context_mutability PASSED [ 38%] tests/server/tasks/test_id_generator.py::TestIDGeneratorContext::test_context_validation PASSED [ 46%] tests/server/tasks/test_id_generator.py::TestIDGeneratorContext::TestIDGenerator::test_cannot_instantiate_abstract_class PASSED [ 53%] tests/server/tasks/test_id_generator.py::TestIDGeneratorContext::TestIDGenerator::test_subclass_must_implement_generate PASSED [ 61%] tests/server/tasks/test_id_generator.py::TestIDGeneratorContext::TestIDGenerator::test_valid_subclass_implementation PASSED [ 69%] tests/server/tasks/test_id_generator.py::TestUUIDGenerator::test_generate_returns_string PASSED [ 76%] tests/server/tasks/test_id_generator.py::TestUUIDGenerator::test_generate_produces_unique_ids PASSED [ 84%] tests/server/tasks/test_id_generator.py::TestUUIDGenerator::test_generate_works_with_various_contexts[none_context] PASSED [ 92%] tests/server/tasks/test_id_generator.py::TestUUIDGenerator::test_generate_works_with_various_contexts[empty_context] PASSED [100%] ============================== 13 passed in 0.04s ============================== ``` - [X] Follow the [`CONTRIBUTING` Guide](https://github.com/a2aproject/a2a-python/blob/main/CONTRIBUTING.md). - [X] Make your Pull Request title in the <https://www.conventionalcommits.org/> specification. - [X] Ensure the tests and linter pass (Run `bash scripts/format.sh` from the repository root to format) - [N/A] Appropriate docs were updated (if necessary) Fixes #<issue_number_goes_here> 🦕 N/A --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Lukasz Kawka <[email protected]>
…updates (a2aproject#603) Bumps the github-actions group with 4 updates in the / directory: [actions/checkout](https://github.com/actions/checkout), [actions/upload-artifact](https://github.com/actions/upload-artifact), [actions/download-artifact](https://github.com/actions/download-artifact) and [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request). Updates `actions/checkout` from 5 to 6 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/actions/checkout/releases">actions/checkout's releases</a>.</em></p> <blockquote> <h2>v6.0.0</h2> <h2>What's Changed</h2> <ul> <li>Update README to include Node.js 24 support details and requirements by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2248">actions/checkout#2248</a></li> <li>Persist creds to a separate file by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2286">actions/checkout#2286</a></li> <li>v6-beta by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2298">actions/checkout#2298</a></li> <li>update readme/changelog for v6 by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2311">actions/checkout#2311</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v5.0.0...v6.0.0">https://github.com/actions/checkout/compare/v5.0.0...v6.0.0</a></p> <h2>v6-beta</h2> <h2>What's Changed</h2> <p>Updated persist-credentials to store the credentials under <code>$RUNNER_TEMP</code> instead of directly in the local git config.</p> <p>This requires a minimum Actions Runner version of <a href="https://github.com/actions/runner/releases/tag/v2.329.0">v2.329.0</a> to access the persisted credentials for <a href="https://docs.github.com/en/actions/tutorials/use-containerized-services/create-a-docker-container-action">Docker container action</a> scenarios.</p> <h2>v5.0.1</h2> <h2>What's Changed</h2> <ul> <li>Port v6 cleanup to v5 by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2301">actions/checkout#2301</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v5...v5.0.1">https://github.com/actions/checkout/compare/v5...v5.0.1</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/actions/checkout/blob/main/CHANGELOG.md">actions/checkout's changelog</a>.</em></p> <blockquote> <h1>Changelog</h1> <h2>v6.0.0</h2> <ul> <li>Persist creds to a separate file by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2286">actions/checkout#2286</a></li> <li>Update README to include Node.js 24 support details and requirements by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2248">actions/checkout#2248</a></li> </ul> <h2>v5.0.1</h2> <ul> <li>Port v6 cleanup to v5 by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2301">actions/checkout#2301</a></li> </ul> <h2>v5.0.0</h2> <ul> <li>Update actions checkout to use node 24 by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li> </ul> <h2>v4.3.1</h2> <ul> <li>Port v6 cleanup to v4 by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2305">actions/checkout#2305</a></li> </ul> <h2>v4.3.0</h2> <ul> <li>docs: update README.md by <a href="https://github.com/motss"><code>@motss</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li> <li>Add internal repos for checking out multiple repositories by <a href="https://github.com/mouismail"><code>@mouismail</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li> <li>Documentation update - add recommended permissions to Readme by <a href="https://github.com/benwells"><code>@benwells</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li> <li>Adjust positioning of user email note and permissions heading by <a href="https://github.com/joshmgross"><code>@joshmgross</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li> <li>Update README.md by <a href="https://github.com/nebuk89"><code>@nebuk89</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li> <li>Update CODEOWNERS for actions by <a href="https://github.com/TingluoHuang"><code>@TingluoHuang</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li> <li>Update package dependencies by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li> </ul> <h2>v4.2.2</h2> <ul> <li><code>url-helper.ts</code> now leverages well-known environment variables by <a href="https://github.com/jww3"><code>@jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li> <li>Expand unit test coverage for <code>isGhes</code> by <a href="https://github.com/jww3"><code>@jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li> </ul> <h2>v4.2.1</h2> <ul> <li>Check out other refs/* by commit if provided, fall back to ref by <a href="https://github.com/orhantoy"><code>@orhantoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li> </ul> <h2>v4.2.0</h2> <ul> <li>Add Ref and Commit outputs by <a href="https://github.com/lucacome"><code>@lucacome</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1180">actions/checkout#1180</a></li> <li>Dependency updates by <a href="https://github.com/dependabot"><code>@dependabot</code></a>- <a href="https://redirect.github.com/actions/checkout/pull/1777">actions/checkout#1777</a>, <a href="https://redirect.github.com/actions/checkout/pull/1872">actions/checkout#1872</a></li> </ul> <h2>v4.1.7</h2> <ul> <li>Bump the minor-npm-dependencies group across 1 directory with 4 updates by <a href="https://github.com/dependabot"><code>@dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1739">actions/checkout#1739</a></li> <li>Bump actions/checkout from 3 to 4 by <a href="https://github.com/dependabot"><code>@dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1697">actions/checkout#1697</a></li> <li>Check out other refs/* by commit by <a href="https://github.com/orhantoy"><code>@orhantoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1774">actions/checkout#1774</a></li> <li>Pin actions/checkout's own workflows to a known, good, stable version. by <a href="https://github.com/jww3"><code>@jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1776">actions/checkout#1776</a></li> </ul> <h2>v4.1.6</h2> <ul> <li>Check platform to set archive extension appropriately by <a href="https://github.com/cory-miller"><code>@cory-miller</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1732">actions/checkout#1732</a></li> </ul> <h2>v4.1.5</h2> <ul> <li>Update NPM dependencies by <a href="https://github.com/cory-miller"><code>@cory-miller</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1703">actions/checkout#1703</a></li> <li>Bump github/codeql-action from 2 to 3 by <a href="https://github.com/dependabot"><code>@dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1694">actions/checkout#1694</a></li> <li>Bump actions/setup-node from 1 to 4 by <a href="https://github.com/dependabot"><code>@dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1696">actions/checkout#1696</a></li> <li>Bump actions/upload-artifact from 2 to 4 by <a href="https://github.com/dependabot"><code>@dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1695">actions/checkout#1695</a></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/actions/checkout/commit/8e8c483db84b4bee98b60c0593521ed34d9990e8"><code>8e8c483</code></a> Clarify v6 README (<a href="https://redirect.github.com/actions/checkout/issues/2328">#2328</a>)</li> <li><a href="https://github.com/actions/checkout/commit/033fa0dc0b82693d8986f1016a0ec2c5e7d9cbb1"><code>033fa0d</code></a> Add worktree support for persist-credentials includeIf (<a href="https://redirect.github.com/actions/checkout/issues/2327">#2327</a>)</li> <li><a href="https://github.com/actions/checkout/commit/c2d88d3ecc89a9ef08eebf45d9637801dcee7eb5"><code>c2d88d3</code></a> Update all references from v5 and v4 to v6 (<a href="https://redirect.github.com/actions/checkout/issues/2314">#2314</a>)</li> <li><a href="https://github.com/actions/checkout/commit/1af3b93b6815bc44a9784bd300feb67ff0d1eeb3"><code>1af3b93</code></a> update readme/changelog for v6 (<a href="https://redirect.github.com/actions/checkout/issues/2311">#2311</a>)</li> <li><a href="https://github.com/actions/checkout/commit/71cf2267d89c5cb81562390fa70a37fa40b1305e"><code>71cf226</code></a> v6-beta (<a href="https://redirect.github.com/actions/checkout/issues/2298">#2298</a>)</li> <li><a href="https://github.com/actions/checkout/commit/069c6959146423d11cd0184e6accf28f9d45f06e"><code>069c695</code></a> Persist creds to a separate file (<a href="https://redirect.github.com/actions/checkout/issues/2286">#2286</a>)</li> <li><a href="https://github.com/actions/checkout/commit/ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493"><code>ff7abcd</code></a> Update README to include Node.js 24 support details and requirements (<a href="https://redirect.github.com/actions/checkout/issues/2248">#2248</a>)</li> <li>See full diff in <a href="https://github.com/actions/checkout/compare/v5...v6">compare view</a></li> </ul> </details> <br /> Updates `actions/upload-artifact` from 5 to 6 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/actions/upload-artifact/releases">actions/upload-artifact's releases</a>.</em></p> <blockquote> <h2>v6.0.0</h2> <h2>v6 - What's new</h2> <blockquote> <p>[!IMPORTANT] actions/upload-artifact@v6 now runs on Node.js 24 (<code>runs.using: node24</code>) and requires a minimum Actions Runner version of 2.327.1. If you are using self-hosted runners, ensure they are updated before upgrading.</p> </blockquote> <h3>Node.js 24</h3> <p>This release updates the runtime to Node.js 24. v5 had preliminary support for Node.js 24, however this action was by default still running on Node.js 20. Now this action by default will run on Node.js 24.</p> <h2>What's Changed</h2> <ul> <li>Upload Artifact Node 24 support by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/upload-artifact/pull/719">actions/upload-artifact#719</a></li> <li>fix: update <code>@actions/artifact</code> for Node.js 24 punycode deprecation by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/upload-artifact/pull/744">actions/upload-artifact#744</a></li> <li>prepare release v6.0.0 for Node.js 24 support by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/upload-artifact/pull/745">actions/upload-artifact#745</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/upload-artifact/compare/v5.0.0...v6.0.0">https://github.com/actions/upload-artifact/compare/v5.0.0...v6.0.0</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/actions/upload-artifact/commit/b7c566a772e6b6bfb58ed0dc250532a479d7789f"><code>b7c566a</code></a> Merge pull request <a href="https://redirect.github.com/actions/upload-artifact/issues/745">#745</a> from actions/upload-artifact-v6-release</li> <li><a href="https://github.com/actions/upload-artifact/commit/e516bc8500aaf3d07d591fcd4ae6ab5f9c391d5b"><code>e516bc8</code></a> docs: correct description of Node.js 24 support in README</li> <li><a href="https://github.com/actions/upload-artifact/commit/ddc45ed9bca9b38dbd643978d88e3981cdc91415"><code>ddc45ed</code></a> docs: update README to correct action name for Node.js 24 support</li> <li><a href="https://github.com/actions/upload-artifact/commit/615b319bd27bb32c3d64dca6b6ed6974d5fbe653"><code>615b319</code></a> chore: release v6.0.0 for Node.js 24 support</li> <li><a href="https://github.com/actions/upload-artifact/commit/017748b48f8610ca8e6af1222f4a618e84a9c703"><code>017748b</code></a> Merge pull request <a href="https://redirect.github.com/actions/upload-artifact/issues/744">#744</a> from actions/fix-storage-blob</li> <li><a href="https://github.com/actions/upload-artifact/commit/38d4c7997f5510fcc41fc4aae2a6b97becdbe7fc"><code>38d4c79</code></a> chore: rebuild dist</li> <li><a href="https://github.com/actions/upload-artifact/commit/7d27270e0cfd253e666c44abac0711308d2d042f"><code>7d27270</code></a> chore: add missing license cache files for <code>@actions/core</code>, <code>@actions/io</code>, and mi...</li> <li><a href="https://github.com/actions/upload-artifact/commit/5f643d3c9475505ccaf26d686ffbfb71a8387261"><code>5f643d3</code></a> chore: update license files for <code>@actions/artifact</code><a href="https://github.com/5"><code>@5</code></a>.0.1 dependencies</li> <li><a href="https://github.com/actions/upload-artifact/commit/1df1684032c88614064493e1a0478fcb3583e1d0"><code>1df1684</code></a> chore: update package-lock.json with <code>@actions/artifact</code><a href="https://github.com/5"><code>@5</code></a>.0.1</li> <li><a href="https://github.com/actions/upload-artifact/commit/b5b1a918401ee270935b6b1d857ae66c85f3be6f"><code>b5b1a91</code></a> fix: update <code>@actions/artifact</code> to ^5.0.0 for Node.js 24 punycode fix</li> <li>Additional commits viewable in <a href="https://github.com/actions/upload-artifact/compare/v5...v6">compare view</a></li> </ul> </details> <br /> Updates `actions/download-artifact` from 6 to 7 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/actions/download-artifact/releases">actions/download-artifact's releases</a>.</em></p> <blockquote> <h2>v7.0.0</h2> <h2>v7 - What's new</h2> <blockquote> <p>[!IMPORTANT] actions/download-artifact@v7 now runs on Node.js 24 (<code>runs.using: node24</code>) and requires a minimum Actions Runner version of 2.327.1. If you are using self-hosted runners, ensure they are updated before upgrading.</p> </blockquote> <h3>Node.js 24</h3> <p>This release updates the runtime to Node.js 24. v6 had preliminary support for Node 24, however this action was by default still running on Node.js 20. Now this action by default will run on Node.js 24.</p> <h2>What's Changed</h2> <ul> <li>Update GHES guidance to include reference to Node 20 version by <a href="https://github.com/patrikpolyak"><code>@patrikpolyak</code></a> in <a href="https://redirect.github.com/actions/download-artifact/pull/440">actions/download-artifact#440</a></li> <li>Download Artifact Node24 support by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/download-artifact/pull/415">actions/download-artifact#415</a></li> <li>fix: update <code>@actions/artifact</code> to fix Node.js 24 punycode deprecation by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/download-artifact/pull/451">actions/download-artifact#451</a></li> <li>prepare release v7.0.0 for Node.js 24 support by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/download-artifact/pull/452">actions/download-artifact#452</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/patrikpolyak"><code>@patrikpolyak</code></a> made their first contribution in <a href="https://redirect.github.com/actions/download-artifact/pull/440">actions/download-artifact#440</a></li> <li><a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> made their first contribution in <a href="https://redirect.github.com/actions/download-artifact/pull/415">actions/download-artifact#415</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/download-artifact/compare/v6.0.0...v7.0.0">https://github.com/actions/download-artifact/compare/v6.0.0...v7.0.0</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/actions/download-artifact/commit/37930b1c2abaa49bbe596cd826c3c89aef350131"><code>37930b1</code></a> Merge pull request <a href="https://redirect.github.com/actions/download-artifact/issues/452">#452</a> from actions/download-artifact-v7-release</li> <li><a href="https://github.com/actions/download-artifact/commit/72582b9e0acd370909e83fa4a1fd0fca3ad452d8"><code>72582b9</code></a> doc: update readme</li> <li><a href="https://github.com/actions/download-artifact/commit/0d2ec9d4cbcefe257d822f108de2a1f15f8da9f6"><code>0d2ec9d</code></a> chore: release v7.0.0 for Node.js 24 support</li> <li><a href="https://github.com/actions/download-artifact/commit/fd7ae8fda6dc16277a9ffbc91cdb0eedf156e912"><code>fd7ae8f</code></a> Merge pull request <a href="https://redirect.github.com/actions/download-artifact/issues/451">#451</a> from actions/fix-storage-blob</li> <li><a href="https://github.com/actions/download-artifact/commit/d484700543354b15886d6a52910cf61b7f1d2b27"><code>d484700</code></a> chore: restore minimatch.dep.yml license file</li> <li><a href="https://github.com/actions/download-artifact/commit/03a808050efe42bb6ad85281890afd4e4546672c"><code>03a8080</code></a> chore: remove obsolete dependency license files</li> <li><a href="https://github.com/actions/download-artifact/commit/56fe6d904b0968950f8b68ea17774c54973ed5e2"><code>56fe6d9</code></a> chore: update <code>@actions/artifact</code> license file to 5.0.1</li> <li><a href="https://github.com/actions/download-artifact/commit/8e3ebc4ab4d2e095e5eb44ba1a4a53b6b03976ad"><code>8e3ebc4</code></a> chore: update package-lock.json with <code>@actions/artifact</code><a href="https://github.com/5"><code>@5</code></a>.0.1</li> <li><a href="https://github.com/actions/download-artifact/commit/1e3c4b4d4906c98ab57453c24efefdf16c078044"><code>1e3c4b4</code></a> fix: update <code>@actions/artifact</code> to ^5.0.0 for Node.js 24 punycode fix</li> <li><a href="https://github.com/actions/download-artifact/commit/458627d354794c71bc386c8d5839d20b5885fe2a"><code>458627d</code></a> chore: use local <code>@actions/artifact</code> package for Node.js 24 testing</li> <li>Additional commits viewable in <a href="https://github.com/actions/download-artifact/compare/v6...v7">compare view</a></li> </ul> </details> <br /> Updates `peter-evans/create-pull-request` from 7 to 8 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/peter-evans/create-pull-request/releases">peter-evans/create-pull-request's releases</a>.</em></p> <blockquote> <h2>Create Pull Request v8.0.0</h2> <h2>What's new in v8</h2> <ul> <li>Requires <a href="https://github.com/actions/runner/releases/tag/v2.327.1">Actions Runner v2.327.1</a> or later if you are using a self-hosted runner for Node 24 support.</li> </ul> <h2>What's Changed</h2> <ul> <li>chore: Update checkout action version to v6 by <a href="https://github.com/yonas"><code>@yonas</code></a> in <a href="https://redirect.github.com/peter-evans/create-pull-request/pull/4258">peter-evans/create-pull-request#4258</a></li> <li>Update actions/checkout references to <a href="https://github.com/v6"><code>@v6</code></a> in docs by <a href="https://github.com/Copilot"><code>@Copilot</code></a> in <a href="https://redirect.github.com/peter-evans/create-pull-request/pull/4259">peter-evans/create-pull-request#4259</a></li> <li>feat: v8 by <a href="https://github.com/peter-evans"><code>@peter-evans</code></a> in <a href="https://redirect.github.com/peter-evans/create-pull-request/pull/4260">peter-evans/create-pull-request#4260</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/yonas"><code>@yonas</code></a> made their first contribution in <a href="https://redirect.github.com/peter-evans/create-pull-request/pull/4258">peter-evans/create-pull-request#4258</a></li> <li><a href="https://github.com/Copilot"><code>@Copilot</code></a> made their first contribution in <a href="https://redirect.github.com/peter-evans/create-pull-request/pull/4259">peter-evans/create-pull-request#4259</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/peter-evans/create-pull-request/compare/v7.0.11...v8.0.0">https://github.com/peter-evans/create-pull-request/compare/v7.0.11...v8.0.0</a></p> <h2>Create Pull Request v7.0.11</h2> <h2>What's Changed</h2> <ul> <li>fix: restrict remote prune to self-hosted runners by <a href="https://github.com/peter-evans"><code>@peter-evans</code></a> in <a href="https://redirect.github.com/peter-evans/create-pull-request/pull/4250">peter-evans/create-pull-request#4250</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/peter-evans/create-pull-request/compare/v7.0.10...v7.0.11">https://github.com/peter-evans/create-pull-request/compare/v7.0.10...v7.0.11</a></p> <h2>Create Pull Request v7.0.10</h2> <p>⚙️ Fixes an issue where updating a pull request failed when targeting a forked repository with the same owner as its parent.</p> <h2>What's Changed</h2> <ul> <li>build(deps): bump the github-actions group with 2 updates by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/peter-evans/create-pull-request/pull/4235">peter-evans/create-pull-request#4235</a></li> <li>build(deps-dev): bump prettier from 3.6.2 to 3.7.3 in the npm group by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/peter-evans/create-pull-request/pull/4240">peter-evans/create-pull-request#4240</a></li> <li>fix: provider list pulls fallback for multi fork same owner by <a href="https://github.com/peter-evans"><code>@peter-evans</code></a> in <a href="https://redirect.github.com/peter-evans/create-pull-request/pull/4245">peter-evans/create-pull-request#4245</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/obnyis"><code>@obnyis</code></a> made their first contribution in <a href="https://redirect.github.com/peter-evans/create-pull-request/pull/4064">peter-evans/create-pull-request#4064</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/peter-evans/create-pull-request/compare/v7.0.9...v7.0.10">https://github.com/peter-evans/create-pull-request/compare/v7.0.9...v7.0.10</a></p> <h2>Create Pull Request v7.0.9</h2> <p>⚙️ Fixes an <a href="https://redirect.github.com/peter-evans/create-pull-request/issues/4228">incompatibility</a> with the recently released <code>actions/checkout@v6</code>.</p> <h2>What's Changed</h2> <ul> <li>~70 dependency updates by <a href="https://github.com/dependabot"><code>@dependabot</code></a></li> <li>docs: fix workaround description about <code>ready_for_review</code> by <a href="https://github.com/ybiquitous"><code>@ybiquitous</code></a> in <a href="https://redirect.github.com/peter-evans/create-pull-request/pull/3939">peter-evans/create-pull-request#3939</a></li> <li>Docs: <code>add-paths</code> default behavior by <a href="https://github.com/joeflack4"><code>@joeflack4</code></a> in <a href="https://redirect.github.com/peter-evans/create-pull-request/pull/3928">peter-evans/create-pull-request#3928</a></li> <li>docs: update to create-github-app-token v2 by <a href="https://github.com/Goooler"><code>@Goooler</code></a> in <a href="https://redirect.github.com/peter-evans/create-pull-request/pull/4063">peter-evans/create-pull-request#4063</a></li> <li>Fix compatibility with actions/checkout@v6 by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/peter-evans/create-pull-request/pull/4230">peter-evans/create-pull-request#4230</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/joeflack4"><code>@joeflack4</code></a> made their first contribution in <a href="https://redirect.github.com/peter-evans/create-pull-request/pull/3928">peter-evans/create-pull-request#3928</a></li> <li><a href="https://github.com/Goooler"><code>@Goooler</code></a> made their first contribution in <a href="https://redirect.github.com/peter-evans/create-pull-request/pull/4063">peter-evans/create-pull-request#4063</a></li> <li><a href="https://github.com/ericsciple"><code>@ericsciple</code></a> made their first contribution in <a href="https://redirect.github.com/peter-evans/create-pull-request/pull/4230">peter-evans/create-pull-request#4230</a></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/peter-evans/create-pull-request/commit/98357b18bf14b5342f975ff684046ec3b2a07725"><code>98357b1</code></a> feat: v8 (<a href="https://redirect.github.com/peter-evans/create-pull-request/issues/4260">#4260</a>)</li> <li><a href="https://github.com/peter-evans/create-pull-request/commit/41c0e4b7899a4a0922bf899d64c5f25738cfe356"><code>41c0e4b</code></a> Update actions/checkout references to <a href="https://github.com/v6"><code>@v6</code></a> in docs (<a href="https://redirect.github.com/peter-evans/create-pull-request/issues/4259">#4259</a>)</li> <li><a href="https://github.com/peter-evans/create-pull-request/commit/994332de4c8124517167807167073cf397678768"><code>994332d</code></a> chore: Update checkout action version to v6 (<a href="https://redirect.github.com/peter-evans/create-pull-request/issues/4258">#4258</a>)</li> <li>See full diff in <a href="https://github.com/peter-evans/create-pull-request/compare/v7...v8">compare view</a></li> </ul> </details> <br /> Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions </details> Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Lukasz Kawka <[email protected]>
lkawka
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Luca, thanks for the PR; apologies for the delay.
The team agrees with moving to proto-based types. Please address Sam's open comments, but otherwise, it looks good.
Proposed next steps:
- Resolve issues and submit to the a2aproject:1.0-a2a_proto_refactor branch.
- Merge into 1.0-dev via a separate PR to avoid conflicts with existing implementations.
src/a2a/client/auth/interceptor.py
Outdated
| which = scheme.WhichOneof('scheme') | ||
| if which == 'api_key_security_scheme': | ||
| return scheme.api_key_security_scheme | ||
| elif which == 'http_auth_security_scheme': | ||
| return scheme.http_auth_security_scheme | ||
| elif which == 'oauth2_security_scheme': | ||
| return scheme.oauth2_security_scheme | ||
| elif which == 'open_id_connect_security_scheme': | ||
| return scheme.open_id_connect_security_scheme | ||
| elif which == 'mtls_security_scheme': | ||
| return scheme.mtls_security_scheme | ||
| return None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
| for part in request.parts: | ||
| if isinstance(part.root, TextPart) and not part.root.text: | ||
| raise ValueError('TextPart content cannot be empty') | ||
| if part.text is not None and not part.text: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
| TRANSPORT_GRPC = 'GRPC' | ||
|
|
||
|
|
||
| class TransportProtocol: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a good candidate for StrEnum
| task_id=params.id, | ||
| name=params.name, | ||
| push_notification_config=push_notification_config[0], | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
This commit resolves extensive test failures caused by recent Protocol Buffer changes in a2a_pb2. Key changes: - Removed invalid 'AgentCard.url' references; updated 'RestTransport' and tests to use 'supported_interfaces'. - Updated 'AgentCard' capability assertions to use 'capabilities.extended_agent_card'. - Fixed 'BaseClient.send_message' usage in integration tests to use 'request' kwarg instead of 'message'. - Updated assertion logic in integration tests to check 'received_params.message'. - verified all tests pass including database integration tests. Signed-off-by: Luca Muscariello <[email protected]>
Signed-off-by: Luca Muscariello <[email protected]>
601ef0b to
a680c18
Compare
|
@lkawka I will go through all the remaining comments on Monday. Thanks for the review. |
|
@Tehsmash could you please check again? I am going to recheck all the previous comments on Monday but please recheck as well. I included the latest updates based on the merge queue in the spec based on the latest TSC votes. We'll see on Tue if the spec can be considered complete for v1. |
67f27a8 to
8e5ab33
Compare
Summary
This PR migrates the a2a-python SDK from Pydantic-based types to protobuf-generated types, completing the upgrade to A2A v1.0. Fixes #559
Breaking Changes
a2a_pb2Partusage fromPart(root=TextPart(text=...))toPart(text=...)Roleenum fromRole.user/Role.agenttoRole.ROLE_USER/Role.ROLE_AGENTTaskStateenum to useTASK_STATE_*prefixChanges
a2a_pb2model_dump()withMessageToDict()for JSON serializationmodel_copy(deep=True)withCopyFrom()for proto cloningproto_utilsmodule with identity conversion utilitiesSubscribeToTaskinstead ofTaskSubscriptionTesting
Related
Builds on top of PR #556
Release-As: 1.0.0